上一篇提到了怎麼將Power BI快速的Embedded到你的網站,但是前一天的兩種方法 - 發行至Web、安全內嵌,都有一些自己的問題,所以如果你的問題沒辦法解決,那Power BI Embedded For Develop可能會是你最佳的選擇! 本篇會把如何把Report、Dashboard嵌入到網頁內!
準備
首先呢,如果我們想要使用Embedded的服務,必須先註冊Embedded,基本上就是填一些資訊,到最後一步的時候下載範例
也可以使用Git的方式將專案下載下來
git clone https://github.com/microsoft/PowerBI-Developer-Samples.git
進入Python目錄
cd PowerBI-Developer-Samples-master/Python/Embed for your customers/
安裝依賴
pip install requirements.txt
接著在Config.py填你的資料,如果忘記上面的資料可以到Azure Portal的Azure Active Diretory的應用程式註冊找一下
config.py
class BaseConfig(object):
# Can be set to 'MasterUser' or 'ServicePrincipal'
AUTHENTICATION_MODE = 'MasterUser'
# Workspace Id in which the report is present
WORKSPACE_ID = '' <- Power BI的WorkSpace ID
# Report Id for which Embed token needs to be generated
REPORT_ID = '' <- Power BI的Report ID
# Id of the Azure tenant in which AAD app and Power BI report is hosted. Required only for ServicePrincipal authentication mode.
TENANT_ID = '' <- Azure Active Diretory的租用戶識別碼
# Client Id (Application Id) of the AAD app
CLIENT_ID = '' <- Azure Active Diretory的用戶端識別碼
# Client Secret (App Secret) of the AAD app. Required only for ServicePrincipal authentication mode.
CLIENT_SECRET = '' <- Azure Active Diretory的憑證與秘密
# Scope of AAD app. Use the below configuration to use all the permissions provided in the AAD app through Azure portal.
SCOPE = ['https://analysis.windows.net/powerbi/api/.default']
# URL used for initiating authorization request
AUTHORITY = 'https://login.microsoftonline.com/organizations'
# Master user email address. Required only for MasterUser authentication mode.
POWER_BI_USER = ''
# Master user email password. Required only for MasterUser authentication mode.
POWER_BI_PASS = ''
接下來只要python app.py就可以看到網頁了!!
從程式碼裡面的** powerbiembedding/static/index.js
index.js
$(function () {
var models = window['powerbi-client'].models;
var reportLoadConfig = {
type: "report", <- 將這個地方改成dashboard
tokenType: models.TokenType.Embed,
/*
// Enable this setting to remove gray shoulders from embedded report
settings: {
background: models.BackgroundType.Transparent
}
*/
};
var reportContainer = $("#report-container").get(0);
// Initialize iframe for embedding report
powerbi.bootstrap(reportContainer, reportLoadConfig);
$.ajax({
type: "GET",
url: "/getembedinfo",
dataType: "json",
success: function (data) {
embedData = $.parseJSON(JSON.stringify(data));
reportLoadConfig["accessToken"] = embedData["accessToken"];
reportLoadConfig["embedUrl"] = embedData["embedUrl"];
// Use the token expiry to regenerate Embed token for seamless end user experience
// Refer https://aka.ms/RefreshEmbedToken
tokenExpiry = embedData["tokenExpiry"];
// Embed Power BI report when Access token and Embed URL are available
var report = powerbi.embed(reportContainer, reportLoadConfig);
// Triggers when a report schema is successfully loaded
report.on("loaded", function () {
console.log("Report load successful")
});
// Triggers when a report is successfully embedded in UI
report.on("rendered", function () {
console.log("Report render successful")
});
// Clear any other error handler event
report.off("error");
// Below patch of code is for handling errors that occur during embedding
report.on("error", function (event) {
var errorMsg = event.detail;
// Use errorMsg variable to log error in any destination of choice
console.error(errorMsg);
return;
});
},
error: function (err) {
// Show error container
var errorContainer = $(".error-container");
$(".embed-container").hide();
errorContainer.show();
// Format error message
var errMessageHtml = "<strong> Error Details: </strong> <br/>" + $.parseJSON(err.responseText)['errorMsg'];
errMessageHtml = errMessageHtml.split("\n").join("<br/>")
// Show error message on UI
errorContainer.html(errMessageHtml);
}
});
});
接著把config.py裡面的Report ID改成Dashboard ID,Dashboard ID在網址列就可以看到了
將pbiembedservice.py的程式碼修改成以下
from flask import current_app as app
import requests
import json
def getembedparam(accesstoken):
'''Returns Embed token and Embed URL'''
try:
headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + accesstoken}
reporturl = 'https://api.powerbi.com/v1.0/myorg/groups/' + app.config['WORKSPACE_ID'] + '/dashboards/' + app.config['REPORT_ID']
apiresponse = None
try:
apiresponse = requests.get(reporturl, headers=headers)
if app.debug:
print('Embed URL Request ID: ', apiresponse.headers.get('RequestId'))
except Exception as ex:
raise Exception('Error while retrieving report Embed URL\n')
if not apiresponse:
raise Exception('Error while retrieving report Embed URL\n' + apiresponse.reason + '\nRequestId: ' + apiresponse.headers.get('RequestId'))
try:
apiresponse = json.loads(apiresponse.text)
embedurl = apiresponse['embedUrl']
datasetId = apiresponse['id']
except Exception as ex:
raise Exception('Error while extracting Embed URL from API response\n' + apiresponse.text)
# Get embed token
embedtokenurl = 'https://api.powerbi.com/v1.0/myorg/groups/'+ app.config['WORKSPACE_ID'] + '/dashboards/' + app.config['REPORT_ID'] + '/GenerateToken'
body = {
'accessLevel': 'View',
'datasetId': app.config['DATASET_ID']
}
apiresponse = None
try:
# Generate Embed token for multiple workspaces, datasets, and reports. Refer https://aka.ms/MultiResourceEmbedToken
apiresponse = requests.post(embedtokenurl, data=json.dumps(body), headers=headers)
if app.debug:
print('Embed token Request ID: ', apiresponse.headers.get('RequestId'))
except:
raise Exception('Error while invoking Embed token REST API endpoint\n')
if not apiresponse:
raise Exception('Error while retrieving report Embed URL\n' + apiresponse.reason + '\nRequestId: ' + apiresponse.headers.get('RequestId'))
try:
apiresponse = json.loads(apiresponse.text)
embedtoken = apiresponse['token']
embedtokenid = apiresponse['tokenId']
tokenexpiry = apiresponse['expiration']
if app.debug:
print('Embed token Expires on: ', tokenexpiry)
print('Embed Token ID: ', embedtokenid)
except Exception as ex:
raise Exception('Error while extracting Embed token from API response\n' + apiresponse.reason)
response = {'accessToken': embedtoken, 'embedUrl': embedurl, 'tokenExpiry': tokenexpiry}
return json.dumps(response)
except Exception as ex:
return json.dumps({'errorMsg': str(ex)}), 500
我們還需要去取得Dashboard的dataset,用範例裡面的試看看,記下DatasetId
再到Config.py新增DatasetId即可
DATASET_ID = 'xxxxxx'
接著就可以在網頁上看到你的Dashboard已經嵌入成功囉~!
因為Dashboard是由磚(Tile)組成的,所以每個磚都會有獨立的Dataset,所以這也是拿DataseId麻煩的地方,如果要嵌入Dashboard就必須透過get Tile去Query所有的DatasetId,才可以產生Dashborad的Embedded Token,藉此才可以嵌入到網頁上!